<!doctype html public "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
<html>
<head>
<title>
 Overview
</title>
<link rel ="stylesheet" type="text/css" href="stylesheet.css" title="Style">
<script>
function asd() {
	
		parent.document.title="jsoner.updater.js Overview";
	
}
</script>
</head>
<body bgcolor="white" onload="asd();">

<!-- ========== START OF NAVBAR ========== -->
<a name="navbar_top"><!-- --></a>
<table border="0" width="100%" cellpadding="1" cellspacing="0">
<tr>
<td colspan=2 bgcolor="#EEEEFF" class="NavBarCell1">
<a name="navbar_top_firstrow"><!-- --></a>
<table border="0" cellpadding="0" cellspacing="3">
  <tr align="center" valign="top">
  
  
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="overview-summary.html"><font class="NavBarFont1"><b>Overview</b></font></a>&nbsp;</td>
  <td bgcolor="#FFFFFF" class="NavBarCell1Rev">	&nbsp;<font class="NavBarFont1Rev"><b>File</b></font>&nbsp;</td>
  

  <td bgcolor="#FFFFFF" class="NavBarCell1"> 	<font class="NavBarFont1">Class</font>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="overview-tree.html"><font class="NavBarFont1"><b>Tree</b></font></a>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="index-all.html"--><font class="NavBarFont1"><b>Index</b></font></a>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="help-doc.html"><font class="NavBarFont1"><b>Help</b></font></a>&nbsp;</td>
  </tr>
</table>
</td>
<td bgcolor="#EEEEFF" align="right" valign="top">
<em>
<b></b></em>
</td>
</tr>

<tr>
<td bgcolor="white" class="NavBarCell2"><font size="-2">
&nbsp;PREV&nbsp;
&nbsp;NEXT</font></td>
<td bgcolor="white" class="NavBarCell2"><font size="-2">
  <a href="index.html" target="_top"><b>FRAMES</b></a>  &nbsp;
&nbsp;<a href="overview-summary.html" target="_top"><b>NO FRAMES</b></a>
&nbsp;&nbsp;
<script>
  <!--
  if(window==top) {
    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
  }
  //-->
</script>
<noscript>
<a href="allclasses-noframe.html" target=""><b>All Classes</b></a>
</noscript>
</font></td>
</tr>
</table>
<!-- =========== END OF NAVBAR =========== -->

<hr>
<center>
	
	   <h2>jsoner.updater.js</h2>
	
</center>

	


<h4>Summary</h4>
<p>
	
		<p>
 The module contains periodicaly Executor and Updatable Action Manager implementaion.
 </p>
 <p>
 Executor represents a simple facility
 for periodical execution of a process with a appointed interval
 between each calls fixed times.
 Executor allows to join several process in one chain or create
 tree structured process chaining.
 Executor provides a mechanism that prevent parallel executions of
 the processes which are tooks longer than the defined interval to execute.
 Executor allows to specify callback function that will be invoked when
 process have been finished.
 </p>
 <p>
 Main purpose of Updatable Action Manager is creation of
 loosely coupled action-based architecture.
 </p>
 <p>
 Updatable Action Manager represents a action manager which
 is a keyboard event listener on the one side and
 periodical process with a appointed interval on the other side.
 Periodical process is used to update actions status and related HTML components
 by particular logic.
 Keyboard event listener allowes to connect hot keys with actions and "magic word" with
 switch actions ON.
 Action invocation API simplify definion of particular action logic
 because action status checker  carries out on separate level.
 Usualy the same logic is used to check action pre-conditions and
 caller DOM node status (enabled-disabled).
 Additionaly, updatable action manager helps to create
 action repeated invocation functionality as a result of a long mouse event.

 Main features of upadatable action manager are:
 <ul>
  <li> Chains action with HTML component/components to change their UI according to action status.
  For example, enable - disable the component or highlight on validation error or
  particular business logic the component.
  <li>Simplify defintion of component event listener because action
  preconditions are  carried out on separate level and automaticaly called
  before action invocation.
  <li> Invokes action by hot key.
  <li> Switch ON - OFF actions by "magic word".
  <li> Updatable action manager helps to create action repeated invocation
  functionality as a result of long mouse event.
 </ul>
 </p><BR/><BR/>
	
</p>

<hr>


    <table border="1" cellpadding="3" cellspacing="0" width="100%">
    <tr bgcolor="#CCCCFF" class="TableHeadingColor">
    <td colspan=2><font size="+2">
    
        <b>Class Summary</b>
    
    </font></td>
    </tr>
    
    <tr bgcolor="white" class="TableRowColor">
    <td width="15%"><b><a href="Executor.html">Executor</a></b></td>
    <td>&nbsp;</td>
    </tr>
    
    <tr bgcolor="white" class="TableRowColor">
    <td width="15%"><b><a href="Updater.html">Updater</a></b></td>
    <td>&nbsp;</td>
    </tr>
    
    </table>
    <hr/> 


<!-- ========== METHOD SUMMARY =========== -->

<!-- ========== END METHOD SUMMARY =========== -->


        <pre class="sourceview"><span class="comment">/**
 * Copyright (c) 2007, Softamis, http://soft-amis.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: Alexey Luchkovsky
 * E-mail: jsoner<span class="attrib">@soft</span>-amis.com
 *
 * Version: 1.24
 * Last modified: 06/06/2007
 */</span>

<span class="comment">/**
 * Class identifier.
 * <span class="attrib">@private</span>
 */</span>
var UPDATER =
{
	version: 1.24
};

<span class="comment">/**
 * <span class="attrib">@fileoverview</span>
 * &lt;p&gt;
 * The module contains periodicaly Executor and Updatable Action Manager implementaion.
 * &lt;/p&gt;
 * &lt;p&gt;
 * Executor represents a simple facility
 * for periodical execution of a process with a appointed interval
 * between each calls fixed times.
 * Executor allows to join several process in one chain or create
 * tree structured process chaining.
 * Executor provides a mechanism that prevent parallel executions of
 * the processes which are tooks longer than the defined interval to execute.
 * Executor allows to specify callback function that will be invoked when
 * process have been finished.
 * &lt;/p&gt;
 * &lt;p&gt;
 * Main purpose of Updatable Action Manager is creation of
 * loosely coupled action-based architecture.
 * &lt;/p&gt;
 * &lt;p&gt;
 * Updatable Action Manager represents a action manager which
 * is a keyboard event listener on the one side and
 * periodical process with a appointed interval on the other side.
 * Periodical process is used to update actions status and related HTML components
 * by particular logic.
 * Keyboard event listener allowes to connect hot keys with actions and "magic word" with
 * switch actions ON.
 * Action invocation API simplify definion of particular action logic
 * because action status checker  carries out on separate level.
 * Usualy the same logic is used to check action pre-conditions and
 * caller DOM node status (enabled-disabled).
 * Additionaly, updatable action manager helps to create
 * action repeated invocation functionality as a result of a long mouse event.
 *
 * Main features of upadatable action manager are:
 * &lt;ul&gt;
 *  &lt;li&gt; Chains action with HTML component/components to change their UI according to action status.
 *  For example, enable - disable the component or highlight on validation error or
 *  particular business logic the component.
 *  &lt;li&gt;Simplify defintion of component event listener because action
 *  preconditions are  carried out on separate level and automaticaly called
 *  before action invocation.
 *  &lt;li&gt; Invokes action by hot key.
 *  &lt;li&gt; Switch ON - OFF actions by "magic word".
 *  &lt;li&gt; Updatable action manager helps to create action repeated invocation
 *  functionality as a result of long mouse event.
 * &lt;/ul&gt;
 * &lt;/p&gt;
 */</span>

var UpdaterDOMUtils = {}

UpdaterDOMUtils.ELEMENT_NODE  = 1;
UpdaterDOMUtils.TEXT_NODE     = 3;
UpdaterDOMUtils.DOCUMENT_NODE = 9;

UpdaterDOMUtils.getElement = <span class="reserved">function</span>(anElement)
{
	var result = COMMONS.isString(anElement) ? document.getElementById(anElement) : anElement;
	<span class="reserved">return</span> result;
};

UpdaterDOMUtils.getDocument = <span class="reserved">function</span>(anElement)
{
	var result = anElement;
	<span class="reserved">if</span> ( anElement.nodeType !== <span class="reserved">this</span>.DOCUMENT_NODE )
	{
	  result = anElement.ownerDocument;
	}
	<span class="reserved">return</span> result;
};

UpdaterDOMUtils.addEventListener = <span class="reserved">function</span>(anObject, aEventName, aCallback)
{
	var element = <span class="reserved">this</span>.getElement(anObject);
	<span class="reserved">if</span> (element )
	{
		<span class="reserved">if</span> (COMMONS.isIE)
		{
			element.attachEvent(<span class="literal">"on"</span> + aEventName, aCallback);
		}
		<span class="reserved">else</span>
		{
			element.addEventListener(aEventName, aCallback, true);
		}
	}
};

UpdaterDOMUtils.removeEventListener = <span class="reserved">function</span>(anObject, aEventName, aCallback)
{
	var element = <span class="reserved">this</span>.getElement(anObject);
	<span class="reserved">if</span> (element )
	{
		<span class="reserved">if</span> (COMMONS.isIE)
		{
			element.detachEvent(<span class="literal">"on"</span> + aEventName, aCallback);
		}
		<span class="reserved">else</span>
		{
			element.removeEventListener(aEventName, aCallback, true);
		}
	}
};

UpdaterDOMUtils.getEventTarget = <span class="reserved">function</span>(anEvent)
{
	var result = anEvent.srcElement || anEvent.target;
	<span class="reserved">if</span> (result &amp;&amp; result.nodeType === <span class="reserved">this</span>.TEXT_NODE )
	{
    result = result.parentNode;
	}
	<span class="reserved">return</span> result;
};

UpdaterDOMUtils.getEventKeyCode = <span class="reserved">function</span>(anEvent)
{
	var result = anEvent.keyCode || anEvent.charCode;
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Executor represents a simple facility
 * for periodical execution of a process with a appointed interval
 * between each calls.
 * Executor allows to join several process in one chain or create
 * tree structured process chaining.
 * Executor provides a mechanism that prevents parallel executions of
 * the processes which  take longer than the defined interval to execute.
 * Executor allows to specify callback function that will be invoked when
 * process have been finished.
 * <span class="attrib">@constuctor</span>
 *
 * <span class="attrib">@param</span> {Function} The process.
 * <span class="attrib">@param</span> {Integer} The appointed interval between each calls of given process.
 * <span class="attrib">@param</span> {Integer} The counter.
 * <span class="attrib">@param</span> {Function} The callback function on executor process finished.
 * <span class="attrib">@param</span> {Boolean} The flag, defines that mechanism that prevenst parallel executions which
 * should be active.
 */</span>
<span class="reserved">function</span> Executor(aProcess, aTimeout, aCounter, aOnStop, aWait)
{
  <span class="reserved">this</span>.fOnStop = aOnStop;
	<span class="reserved">this</span>.fProcess = aProcess;
	<span class="reserved">this</span>.fWait = aWait;
	<span class="reserved">this</span>.fLock = false;
	<span class="reserved">this</span>.fCounter = isNaN(aCounter) ? 1000000 : aCounter;
	<span class="reserved">this</span>.fTimeout = isNaN(aTimeout) ? 500 : aTimeout;
	<span class="reserved">this</span>.fLockCheckerTimeout = Math.round(<span class="reserved">this</span>.fTimeout()/4);
	<span class="reserved">this</span>.fOwnExecutor = null;

	<span class="reserved">this</span>.fJoinedExecutors = [];
	<span class="reserved">this</span>.fLogger = new Logger(<span class="literal">"Executor"</span>);

	<span class="reserved">this</span>.fTaskID = null;
	<span class="reserved">this</span>.fLockCheckerTaskID = null;
}

<span class="comment">/**
 * Indicates that the executed process is locked or any
 * of chained process is locked.
 * The method can be overrided to be corresponding to the particular logic.
 * For example, thread is locked as long as chained threads are  alive.
 *
 * <span class="attrib">@return</span> {Boolean} Returns true is it so, otherwise - false.
 */</span>
Executor.<span class="reserved">prototype</span>.isLocked = <span class="reserved">function</span>()
{
	var result = <span class="reserved">this</span>.fTaskID &amp;&amp; <span class="reserved">this</span>.fLock;
	<span class="reserved">if</span> ( !result )
	{
		var executor;
		<span class="reserved">for</span>( var i = 0; i &lt; <span class="reserved">this</span>.fJoinedExecutors.length; i++)
		{
			executor = <span class="reserved">this</span>.fJoinedExecutors[i];
			<span class="reserved">if</span> ( executor.isLocked() )
			{
				result = true;
				break;
			}
		}
	}
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Indicates that the executor is alive.
 * <span class="attrib">@return</span> {Boolean} Returns true is it so, otherwise - false.
 */</span>
Executor.<span class="reserved">prototype</span>.isAlive = <span class="reserved">function</span>()
{
	<span class="reserved">return</span> <span class="reserved">this</span>.fCounter &gt; 0;
};

<span class="comment">/**
 * Invokes the executor callback on process finished.
 */</span>
Executor.<span class="reserved">prototype</span>.onStopCallBack = <span class="reserved">function</span>()
{
	<span class="reserved">if</span> ( COMMONS.isFunction(<span class="reserved">this</span>.fOnStop) )
	{
		try
		{
			<span class="reserved">this</span>.fOnStop.call(<span class="reserved">this</span>);
		}
		catch(ex)
		{
			<span class="reserved">this</span>.fLogger.error(<span class="literal">"Executor onStop error caused"</span>, ex );
		}
	}
};

<span class="comment">/**
 * Starts an executor thread.
 */</span>
Executor.<span class="reserved">prototype</span>.start = <span class="reserved">function</span>()
{
	<span class="reserved">this</span>.fLock = false;
	<span class="reserved">this</span>.doStart();
};

<span class="comment">/**
 * Periodicaly invokes the  process until
 * the executor counter is more the zerro.
 * <span class="attrib">@private</span>
 */</span>
Executor.<span class="reserved">prototype</span>.doStart = <span class="reserved">function</span>()
{
	var executor = <span class="reserved">this</span>;

	<span class="reserved">if</span> (<span class="reserved">this</span>.fLockCheckerTaskID !== null )
	{
		window.clearTimeout(<span class="reserved">this</span>.fLockCheckerTaskID);
		<span class="reserved">this</span>.fLockCheckerTaskID = null;
	}
	<span class="reserved">if</span> ( <span class="reserved">this</span>.isLocked() )
	{
		<span class="reserved">this</span>.fLockCheckerTaskID = window.setTimeout(<span class="reserved">function</span>()
		{
			executor.doStart();
		}, <span class="reserved">this</span>.fLockCheckerTimeout );
	}
	<span class="reserved">else</span>
	{
		<span class="reserved">if</span> (<span class="reserved">this</span>.fTaskID !== null)
	  {
		  window.clearTimeout(<span class="reserved">this</span>.fTaskID);
		  <span class="reserved">this</span>.fTaskID = null;
	  }
		<span class="reserved">if</span> ( <span class="reserved">this</span>.isAlive() )
		{
			<span class="reserved">if</span> ( COMMONS.isFunction(<span class="reserved">this</span>.fProcess) )
			{
				<span class="reserved">if</span> ( <span class="reserved">this</span>.fWait)
				{
					<span class="reserved">this</span>.fLock = true;
				}
				try
				{
					<span class="reserved">this</span>.fProcess.call(<span class="reserved">this</span>);
				}
				catch(ex)
				{
					<span class="reserved">this</span>.fLogger.error(<span class="literal">"Executor process error caused"</span>, ex );
				}
				<span class="reserved">this</span>.fLock = false;
			}
			<span class="reserved">this</span>.fCounter--;

			<span class="reserved">this</span>.fTaskID = window.setTimeout(<span class="reserved">function</span>()
			{
				executor.doStart()
			}, <span class="reserved">this</span>.fTimeout );
		}
		<span class="reserved">else</span>
		{
			<span class="reserved">this</span>.onStopCallBack();
		}
  }
};

<span class="comment">/**
 * Sets the flag that the executor should  stop executing
 * of current process and all chained threads too.
 */</span>
Executor.<span class="reserved">prototype</span>.stop = <span class="reserved">function</span>()
{
	<span class="reserved">this</span>.fCounter = -1;

	var executor;
	<span class="reserved">for</span>( var i = 0; i &lt; <span class="reserved">this</span>.fJoinedExecutors.length; i++)
	{
		executor = <span class="reserved">this</span>.fJoinedExecutors[i];
		<span class="reserved">if</span> ( executor.isAlive() )
		{
			try
			{
				executor.stop();
			}
			catch(ex)
			{
				<span class="reserved">this</span>.fLogger.error(<span class="literal">"Unable to stop an executor because an error occured"</span>, ex);
			}
		}
	}
};

<span class="comment">/**
 * Forces the executor to stop executing of current process
 * and all chained threads too.
 */</span>
Executor.<span class="reserved">prototype</span>.fireStop = <span class="reserved">function</span>()
{
	var executor;
	<span class="reserved">for</span>( var i = 0; i &lt; <span class="reserved">this</span>.fJoinedExecutors.length; i++)
	{
		executor = <span class="reserved">this</span>.fJoinedExecutors[i];
		try
		{
		  executor.fireStop();
		}
		catch(ex)
		{
			<span class="reserved">this</span>.fLogger.error(<span class="literal">"Unable to stop an executor because an error occured"</span>, ex);
		}
	}

	<span class="reserved">if</span> (<span class="reserved">this</span>.fLockCheckerTaskID !== null )
	{
		window.clearTimeout(<span class="reserved">this</span>.fLockCheckerTaskID);
		<span class="reserved">this</span>.fLockCheckerTaskID = null;
	}
	<span class="reserved">if</span> (<span class="reserved">this</span>.fTaskID !== null)
	{
		window.clearTimeout(<span class="reserved">this</span>.fTaskID);
		<span class="reserved">this</span>.fTaskID = null;
	}
	<span class="reserved">this</span>.onStopCallBack();
	<span class="reserved">this</span>.fCounter = -1;
};

<span class="comment">/**
 * Adds another executor to current for chaining them.
 * Added executor has information about its owner.
 *
 * <span class="attrib">@see</span> #isLocked
 */</span>
Executor.<span class="reserved">prototype</span>.chain = <span class="reserved">function</span>(anExecutor)
{
	<span class="reserved">if</span> ( anExecutor instanceof Executor )
	{
		anExecutor.fOwnExecutor = <span class="reserved">this</span>;
	  <span class="reserved">this</span>.fJoinedExecutors.push(anExecutor);
	}
	<span class="reserved">else</span>
	{
		<span class="reserved">this</span>.fLogger.error(<span class="literal">"joinProcess, illegal argument type: "</span> + anExecutor);
	}
};

<span class="comment">/**
 * Creates updatable action manager.
 * Main purpose of upadatable action manager is creation of
 * loosely coupled action- based architecture.
 *
 * Updatable action manager represents a action manager which
 * is a keyboard event listener on the one side and
 * periodical process with a appointed interval on the other side.
 *
 * Periodical process is used to update actions status and related HTML components
 * by particular logic.
 * Keyboard event listener allowes to connect hot keys with actions and "magic word" with
 * switch actions ON.
 * Action invocation API simplify definion of particular action logic
 * because action status checker is carried out on separate level.
 * Usualy the same logic is used to check action pre-conditions and
 * caller DOM node status (enabled-disabled).
 * Additionaly, updatable action manager helps to create
 * action repeated invocation functionality on long mouse event.
 *
 * Main features of upadatable action manager are:
 * &lt;ul&gt;
 *  &lt;li&gt; Chains action with HTML component/components to change their UI
 *  according to the action status.
 *  For example, enable - disable the component, highlight the component.
 *  &lt;li&gt;Simplify defintion of component event listener because action
 *  preconditions are carried out on separate level and automaticaly called
 *  before action invocation.
 *  &lt;li&gt; Invokes action by hot key.
 *  &lt;li&gt; Switch ON - OFF actions by magic word.
 *  &lt;li&gt; Updatable action manager helps to create action repeated invocation
 *  functionality on long mouse event.
 * &lt;/ul&gt;
 * <span class="attrib">@constructor</span>
 *
 * <span class="attrib">@param</span> {Integer} An interval for periodical update process (in ms).
 * <span class="attrib">@param</span> {Node} The monitored container, document by default.
 */</span>
<span class="reserved">function</span> Updater(aTimeout, aContainer)
{
  <span class="reserved">this</span>.fActions = [];
	<span class="reserved">this</span>.fUIProcessors = new HashMap();
  <span class="reserved">this</span>.fKeys = new HashMap();

	<span class="reserved">this</span>.fKeyBuffer = <span class="literal">""</span>;
	<span class="reserved">this</span>.fKeyBufferSize = -1;

  <span class="reserved">this</span>.fLock = false;
	<span class="reserved">this</span>.fCheckWord = false;
	<span class="reserved">this</span>.fCheckKey = false;

	<span class="reserved">this</span>.fProcessID = null;
	<span class="reserved">this</span>.fAutoRepeatTaskID = null;

	<span class="reserved">this</span>.fTimeout = isNaN(aTimeout) ? 50 : aTimeout;
	<span class="reserved">this</span>.fLogger = new Logger(<span class="literal">"Updater"</span>);

	<span class="reserved">this</span>.fContainer = COMMONS.isObject(aContainer) || document;

  <span class="reserved">this</span>.initKeyMaps();
	<span class="reserved">this</span>.initUIProcessors();
}

Updater.KB_BSP    = 8;
Updater.KB_TAB    = 9;
Updater.KB_CENTER = 12;
Updater.KB_ENTER  = 13;
Updater.KB_CTRL   = 17;
Updater.KB_CAPS   = 20;
Updater.KB_ESC    = 27;
Updater.KB_PAGE_UP   = 33;
Updater.KB_PAGE_DOWN = 34;
Updater.KB_END   = 35;
Updater.KB_HOME  = 36;
Updater.KB_LEFT  = 37;
Updater.KB_UP    = 38;
Updater.KB_RIGHT = 39;
Updater.KB_DOWN  = 40;
Updater.KB_DEL   = 46;
Updater.KB_PLUS  = 107;
Updater.KB_MINUS = 109;
Updater.KB_PLUS_KB  = 61;
Updater.KB_MINUS_KB = 189;

<span class="comment">/**
 * Registers key map to simplify description of of action key chain.
 * <span class="attrib">@param</span> {String} The string that defines key code in
 * the description of action key chain.
 * <span class="attrib">@param</span> {Integer} The key code.
 */</span>
Updater.<span class="reserved">prototype</span>.registerKeyMap = <span class="reserved">function</span>(aName, aCode)
{
  <span class="reserved">this</span>.fKeys.put(aName, aCode);
};

<span class="comment">/**
 * Registers default key map to simplify
 * description of actions key chains.
 */</span>
Updater.<span class="reserved">prototype</span>.initKeyMaps = <span class="reserved">function</span>()
{
  <span class="reserved">this</span>.registerKeyMap(<span class="literal">"LEFT"</span>, Updater.KB_LEFT);
  <span class="reserved">this</span>.registerKeyMap(<span class="literal">"UP"</span>, Updater.KB_UP);
  <span class="reserved">this</span>.registerKeyMap(<span class="literal">"RIGHT"</span>, Updater.KB_RIGHT);
  <span class="reserved">this</span>.registerKeyMap(<span class="literal">"DOWN"</span>, Updater.KB_DOWN);
  <span class="reserved">this</span>.registerKeyMap(<span class="literal">"PAGE_UP"</span>, Updater.KB_PAGE_UP);
  <span class="reserved">this</span>.registerKeyMap(<span class="literal">"PAGE_DOWN"</span>, Updater.KB_PAGE_DOWN);

  <span class="reserved">this</span>.registerKeyMap(<span class="literal">"PLUS"</span>, Updater.KB_PLUS);
  <span class="reserved">this</span>.registerKeyMap(<span class="literal">"PLUSKB"</span>, Updater.KB_PLUS_KB);
  <span class="reserved">this</span>.registerKeyMap(<span class="literal">"MINUS"</span>, Updater.KB_MINUS);
  <span class="reserved">this</span>.registerKeyMap(<span class="literal">"MINUSKB"</span>, Updater.KB_MINUS_KB);

  <span class="reserved">this</span>.registerKeyMap(<span class="literal">"TAB"</span>, Updater.KB_TAB);
  <span class="reserved">this</span>.registerKeyMap(<span class="literal">"CENTER"</span>, Updater.KB_CENTER);
  <span class="reserved">this</span>.registerKeyMap(<span class="literal">"ENTER"</span>, Updater.KB_ENTER);
  <span class="reserved">this</span>.registerKeyMap(<span class="literal">"ESC"</span>, Updater.KB_ESC);
};

<span class="comment">/**
 * Registers UI processor by DOM node name.
 * UI processor represents a function which available change component UI
 * under corresponding action status.
 * Interface of component UI processor is:
 * &lt;code&gt;function(aNode, aStatus)&lt;/code&gt;
 *
 * <span class="attrib">@param</span> {String} The DOM node name.
 * <span class="attrib">@param</span> {Function} The UI processor.
 */</span>
Updater.<span class="reserved">prototype</span>.registerUIProcessor = <span class="reserved">function</span>(aNodeName, aFunction)
{
  <span class="reserved">this</span>.fUIProcessors.put(aNodeName, aFunction);
};

<span class="comment">/**
 * Registers UI processors by defaults.
 * <span class="attrib">@see</span> #registerUIProcessor
 */</span>
Updater.<span class="reserved">prototype</span>.initUIProcessors = <span class="reserved">function</span>()
{
	<span class="reserved">this</span>.registerUIProcessor(<span class="literal">"IMG"</span>, <span class="reserved">this</span>.updateImageUI );
	<span class="reserved">this</span>.registerUIProcessor(<span class="literal">"BUTTON"</span>, <span class="reserved">this</span>.updateControlUI );
	<span class="reserved">this</span>.registerUIProcessor(<span class="literal">"INPUT"</span>, <span class="reserved">this</span>.updateControlUI );

	<span class="reserved">this</span>.registerUIProcessor(<span class="literal">"A"</span>, <span class="reserved">this</span>.updateBlockUI );
	<span class="reserved">this</span>.registerUIProcessor(<span class="literal">"TD"</span>, <span class="reserved">this</span>.updateBlockUI );
	<span class="reserved">this</span>.registerUIProcessor(<span class="literal">"DIV"</span>, <span class="reserved">this</span>.updateBlockUI );
};

<span class="comment">/**
 * Returns UI processor suitable to DOM node and
 * required action status.
 *
 * <span class="attrib">@return</span> {Function} Returns UI processor
 * suitable to DOM node and required status.
 * <span class="attrib">@param</span> {Node} The DOM node.
 * <span class="attrib">@param</span> The action status.
 */</span>
Updater.<span class="reserved">prototype</span>.getUIProcessor = <span class="reserved">function</span>(aNode, aStatus)
{
	var result = undefined;
	<span class="reserved">if</span> ( COMMONS.isObject(aNode) &amp;&amp; aNode.nodeType === UpdaterDOMUtils.ELEMENT_NODE )
	{
		result = <span class="reserved">this</span>.fUIProcessors.get(aNode.nodeName);
	}
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Parses string which  destignates the set of action hot keys to
 * array of array of keystrokes.
 *
 * Hot keys definition examples:
 * &lt;code&gt;Ctrl-Shift-P&lt;/code&gt;
 * &lt;code&gt;Alt-PAGE_UP Alt-Shift-PAGE_UP&lt;/code&gt;
 * &lt;code&gt;CTRL-SHIFT-124 SHIFT-ALT-M&lt;/code&gt;
 *
 * <span class="attrib">@param</span> {String} The string which is destignated
 * the set of action hot keys.
 * <span class="attrib">@return</span> {Array} Returns prepared array of array of keystrokes.
 * For example: [[ALT, 33], [ALT, SHIFT, 33]]
 */</span>
Updater.<span class="reserved">prototype</span>.parseHotKey = <span class="reserved">function</span>(aHotKey)
{
	var result = undefined;
	var code;
	<span class="reserved">if</span> ( COMMONS.isString(aHotKey) )
	{
		result = aHotKey.split(<span class="literal">' '</span>);
		<span class="reserved">for</span> (var i = 0; i &lt; result.length; i++ )
		{
			result[i] = result[i].split(<span class="literal">'-'</span>);
			code = <span class="reserved">this</span>.fKeys.get( result[i][result[i].length - 1] );
			<span class="reserved">if</span> ( code !== undefined )
			{
				result[i][result[i].length - 1] = code;
			}
			<span class="reserved">else</span>
			{
				result[i][result[i].length - 1] = result[i][result[i].length - 1].toUpperCase();
			}
			<span class="reserved">if</span> ( result[i].length &gt; 1)
			{
				var modifier;
				<span class="reserved">for</span> (var j = 0; j &lt; result[i].length - 1; j++ )
				{
					result[i][j] = result[i][j].toUpperCase();
				}
			}
		}
	}
  <span class="reserved">return</span> result;
};

<span class="comment">/**
 * Indicates that the array of array of keystrokes  matches with
 * given keyboard event.
 *
 * <span class="attrib">@return</span> {Boolean} Returns true is it so, otherwise - false.
 * <span class="attrib">@param</span> {Array} The array of array of keystrokes.
 * For example: [[ALT, M], [ALT, SHIFT, L]]
 *
 * <span class="attrib">@param</span> {Event} The keyborad event.
 */</span>
Updater.<span class="reserved">prototype</span>.isMatchedKey = <span class="reserved">function</span>(aKeyStroke, aEvent)
{
	var keyCode = UpdaterDOMUtils.getEventKeyCode(aEvent);

	var result = false;
	var keyStroke;
	<span class="reserved">for</span> (var i = 0; i &lt; aKeyStroke.length; i++)
	{
		keyStroke = aKeyStroke[i];
		<span class="reserved">if</span> ( COMMONS.isNumber(keyStroke[keyStroke.length - 1]) )
		{
			result = keyCode === parseInt(keyStroke[keyStroke.length - 1]);
		}
		<span class="reserved">else</span>
		{
			result = String.fromCharCode(keyCode) === keyStroke[keyStroke.length - 1];
		}

		<span class="reserved">if</span> ( result &amp;&amp; keyStroke.length &gt; 1)
		{
			<span class="reserved">for</span> (var j = 0; j &lt; keyStroke.length - 1; j++)
			{
				<span class="reserved">if</span> ((keyStroke[j] === <span class="literal">"SHIFT"</span> &amp;&amp; !aEvent.shiftKey) ||  (keyStroke[j] === <span class="literal">"CTRL"</span> &amp;&amp; !aEvent.ctrlKey) ||
				    (keyStroke[j] === <span class="literal">"ALT"</span> &amp;&amp; !aEvent.altKey))
				{
					result = false;
					break;
				}
			}
		}
	}
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Starts updatable action manager.
 * <span class="attrib">@see</span> #stop
 */</span>
Updater.<span class="reserved">prototype</span>.start = <span class="reserved">function</span>()
{
	<span class="reserved">this</span>.stop();
	var updater = <span class="reserved">this</span>;

	<span class="reserved">this</span>.fProcessID = window.setInterval(<span class="reserved">function</span>()
	{
		updater.update()
	}, <span class="reserved">this</span>.fTimeout);

	<span class="reserved">if</span> ( <span class="reserved">this</span>.keyup === undefined )
	{
		<span class="reserved">this</span>.keyup = <span class="reserved">function</span>(event)
		{
			<span class="reserved">if</span> ( updater.acceptKeyEvent(event) )
			{
				updater.keyPressed(event);
			}
		};
		UpdaterDOMUtils.addEventListener(<span class="reserved">this</span>.fContainer, <span class="literal">"keyup"</span>, <span class="reserved">this</span>.keyup);
	}
	<span class="reserved">if</span> ( <span class="reserved">this</span>.mouseup === undefined )
	{
		<span class="reserved">this</span>.mouseup = <span class="reserved">function</span> (event)
		{
			updater.mouseUp(event)
		};
		UpdaterDOMUtils.addEventListener(<span class="reserved">this</span>.fContainer, <span class="literal">"mouseup"</span>, <span class="reserved">this</span>.mouseup);
	}
};

<span class="comment">/**
 * Stops updatable action manager.
 * <span class="attrib">@see</span> #destroy
 */</span>
Updater.<span class="reserved">prototype</span>.stop = <span class="reserved">function</span>()
{
	<span class="reserved">if</span> (<span class="reserved">this</span>.fProcessID !== null)
	{
		window.clearInterval(<span class="reserved">this</span>.fProcessID);
		<span class="reserved">this</span>.fProcessID = null;
	}
};

<span class="comment">/**
 * Stops updatable action manager, destroys
 * registered listeners and clears registered actions array.
 *
 * <span class="attrib">@see</span> #stop
 */</span>
Updater.<span class="reserved">prototype</span>.destroy = <span class="reserved">function</span>()
{
	<span class="reserved">this</span>.stop();
	<span class="reserved">if</span> ( <span class="reserved">this</span>.mouseup !== undefined )
	{
		UpdaterDOMUtils.removeEventListener(<span class="reserved">this</span>.fContainer, <span class="literal">"mouseup"</span>, <span class="reserved">this</span>.mouseup);
		<span class="reserved">this</span>.mouseup = undefined;
	}
	<span class="reserved">if</span> ( <span class="reserved">this</span>.keyup !== undefined )
	{
		UpdaterDOMUtils.removeEventListener(<span class="reserved">this</span>.fContainer, <span class="literal">"mouseover"</span>, <span class="reserved">this</span>.keyup);
		<span class="reserved">this</span>.keyup = undefined;
	}
	<span class="reserved">this</span>.fActions = [];
};

<span class="comment">/**
 * Updatable action factory.
 * Creates updatable action by given parameters.
 *
 * Result action status is false and the action
 * is switched OFF by defaults.
 *
 * <span class="attrib">@param</span> {String} The action ID.
 * <span class="attrib">@param</span> {Function} The action body - the method is  invocated by action.
 * <span class="attrib">@param</span> {Function} The action status checker - the method which returns the action status.
 * <span class="attrib">@param</span> {Array} The array of chained with action HTML components ID.
 * <span class="attrib">@param</span> {Array} The action hot keys.
 * <span class="attrib">@param</span> {Integer} The action timeout - interval is ms to invoke action automaticaly.
 * <span class="attrib">@param</span> {String} The "magic word" which is used to switch ON the action (if it is necessary).
 */</span>
Updater.<span class="reserved">prototype</span>.createAction = <span class="reserved">function</span>(aID, anAction, aStatusChecker, anElementsID, aHotKey, aAutoTimeout, aMagicWord )
{
	var result =
	{
		id:aID,
		on:false,
		status:false,
		action:COMMONS.isFunction(anAction) ? anAction : undefined,
	  checker:COMMONS.isFunction(aStatusChecker) ? aStatusChecker : undefined,
	  elements: COMMONS.isArray(anElementsID) ? anElementsID : (COMMONS.isString(anElementsID) ? [anElementsID] : undefined),
	  autoTimeout: isNaN(aAutoTimeout) ? 0 : aAutoTimeout,
		key: COMMONS.isString(aHotKey) ?  <span class="reserved">this</span>.parseHotKey(aHotKey) : undefined,
		word: COMMONS.isString(aMagicWord) ? aMagicWord.toUpperCase() : undefined
	};
	<span class="reserved">return</span> result;
}

<span class="comment">/**
 * Creates updatable action by given parameters and adds its to the action manager.
 *
 * <span class="attrib">@param</span> {String} The action ID.
 * <span class="attrib">@param</span> {Function} The action body - the method is invoked by action.
 * <span class="attrib">@param</span> {Function} The action status checker - the method which returns the action status.
 * <span class="attrib">@param</span> {Array} The array of chained with action HTML components ID.
 * <span class="attrib">@param</span> {Array} The action hot keys.
 * <span class="attrib">@param</span> {Integer} The action timeout - interval is ms to invoke action automaticaly.
 * <span class="attrib">@param</span> {String} The magic word which used to switch on the action (if it necessary).
 */</span>
Updater.<span class="reserved">prototype</span>.addAction = <span class="reserved">function</span>(aID, anAction, aStatusChecker, anElementsID, aHotKey, aAutoTimeout, aMagicWord )
{
	var action = <span class="reserved">this</span>.createAction(aID, anAction, aStatusChecker, anElementsID, aHotKey, aMagicWord, aAutoTimeout);

	<span class="reserved">this</span>.fCheckKey = action !== undefined;
	<span class="reserved">if</span> ( action.word !== undefined  )
	{
		<span class="reserved">this</span>.fCheckWord = true;
		<span class="reserved">this</span>.fKeyBufferSize = Math.max(<span class="reserved">this</span>.fKeyBufferSize, action.word.length);
	}
	var index = <span class="reserved">this</span>.fActions.length;
	<span class="reserved">for</span>(var i = 0; i &lt; index; i++)
  {
		<span class="reserved">if</span> ( <span class="reserved">this</span>.fActions[i].id === action.id )
		{
			index = i;
			break;
		}
	}
  <span class="reserved">this</span>.fActions[index] = action;
};

<span class="comment">/**
 * Returns the updatable action by given ID.
 * If corresponding action can't be obtained it returns undefined.
 *
 * <span class="attrib">@param</span> {String} The action ID.
 * <span class="attrib">@return</span> The updatable action.
 */</span>
Updater.<span class="reserved">prototype</span>.getAction = <span class="reserved">function</span>(aID)
{
	var result = undefined;
	<span class="reserved">for</span>(var i = 0; i &lt; <span class="reserved">this</span>.fActions.length; i++)
	{
		<span class="reserved">if</span> (<span class="reserved">this</span>.fActions[i].id === aID )
		{
			result = <span class="reserved">this</span>.fActions[i];
			break;
		}
	}
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Indicates that the keyboard event is accepted.
 *
 * <span class="attrib">@param</span> {Event} The key up event.
 * <span class="attrib">@return</span> {Boolean} If so it returns true, otherwise it returns false.
 *
 */</span>
Updater.<span class="reserved">prototype</span>.acceptKeyEvent = <span class="reserved">function</span>(aEvent)
{
	var result = false;
	var element = UpdaterDOMUtils.getEventTarget(aEvent);
	<span class="reserved">if</span> ( COMMONS.isObject(element) )
	{
		result = true;
	  <span class="reserved">if</span> (element.nodeName === <span class="literal">"TEXTAREA"</span> || element.nodeName === <span class="literal">"INPUT"</span> ||
	      element.nodeName === <span class="literal">"SELECT"</span> || element.nodeName === <span class="literal">"BUTTON"</span>)
	  {
		  result = COMMONS.toBoolean(element.readOnly) || COMMONS.toBoolean(element.disabled);
	  }
  }
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Switches actions to ON/OFF.
 * Actions that are not switched in ON status are ignored.
 *
 * <span class="attrib">@param</span> The Order of actions ID.
 * &lt;code&gt; switchAction("action1", "action2",..., true);&lt;/code&gt;
 * <span class="attrib">@param</span> {Boolean} The actions switch status.
 */</span>
Updater.<span class="reserved">prototype</span>.switchAction = <span class="reserved">function</span>(aID, anON)
{
	<span class="reserved">for</span>(var i = 0; i &lt; arguments.length - 1; i++)
	{
		var action = <span class="reserved">this</span>.getAction(arguments[i]);
		<span class="reserved">if</span> ( COMMONS.isObject(action) )
		{
			action.on = arguments[ arguments.length - 1 ];
		}
	}
};

<span class="comment">/**
 * Indicates that the action should be processed.
 *
 * <span class="attrib">@return</span> {Boolean} Returns true if the given action is switched ON
 * and action status is true, otherwise - returns false.
 * <span class="attrib">@param</span> The updatable action.
 */</span>
Updater.<span class="reserved">prototype</span>.acceptAction = <span class="reserved">function</span>(anAction)
{
	var result = COMMONS.isObject(anAction) &amp;&amp; anAction.on &amp;&amp; anAction.status;
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Action manager keyboard listener.
 * Tries to find an action by key code and
 * if the corresponding action is available invoke its.
 *
 * <span class="attrib">@param</span> {Event} The keyboard event.
 */</span>
Updater.<span class="reserved">prototype</span>.keyPressed = <span class="reserved">function</span>(event)
{
	var result = null;
	var action;

  <span class="reserved">if</span> (<span class="reserved">this</span>.fAutoRepeatTaskID !== null)
	{
		window.clearTimeout(<span class="reserved">this</span>.fAutoRepeatTaskID);
		<span class="reserved">this</span>.fAutoRepeatTaskID = null;
	}

  <span class="reserved">if</span> ( !<span class="reserved">this</span>.fLock &amp;&amp; (<span class="reserved">this</span>.fCheckWord || <span class="reserved">this</span>.fCheckKey) )
  {
    var keyCode = UpdaterDOMUtils.getEventKeyCode(event);
	  <span class="reserved">if</span> ( <span class="reserved">this</span>.fCheckWord )
	  {
		  <span class="reserved">if</span> (<span class="reserved">this</span>.fKeyBuffer.length &gt;= <span class="reserved">this</span>.fKeyBufferSize)
		  {
				<span class="reserved">this</span>.fKeyBuffer = <span class="reserved">this</span>.fKeyBuffer.substring(1, <span class="reserved">this</span>.fKeyBuffer.length);
			}
		  <span class="reserved">this</span>.fKeyBuffer += String.fromCharCode(keyCode);
			<span class="reserved">for</span>(var i = 0; i &lt; <span class="reserved">this</span>.fActions.length; i++)
			{
				action = <span class="reserved">this</span>.fActions[i];
				<span class="reserved">if</span> ( !action.on &amp;&amp; (<span class="reserved">this</span>.fKeyBuffer === action.word) )
				{
					action.on = true;
				}
			}
	  }

	  <span class="reserved">if</span> ( <span class="reserved">this</span>.fCheckKey )
	  {
			<span class="reserved">for</span>(var i = 0; i &lt; <span class="reserved">this</span>.fActions.length; i++)
			{
				action = <span class="reserved">this</span>.fActions[i];
				<span class="reserved">if</span> ( <span class="reserved">this</span>.acceptAction(action) &amp;&amp; action.key !== undefined )
				{
					<span class="reserved">if</span> ( <span class="reserved">this</span>.isMatchedKey(action.key, event) )
					{
						<span class="reserved">this</span>.fLock = true;
						try
						{
							result = action.action.call(<span class="reserved">this</span>, event);
						}
						catch(ex)
						{
							<span class="reserved">this</span>.fLogger.error(<span class="literal">"keyPressed, call of the action "</span> + action.id +<span class="literal">" an error caused"</span>, ex);
						}

					  var updater = <span class="reserved">this</span>;
						window.setTimeout(<span class="reserved">function</span>()
						{
							updater.fLock = false
						}, 10);
						break;
					}
				}
			}
		}
  }
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Periodically updates actions status and related HTML components.
 * <span class="attrib">@see</span> #getUIProcessor
 */</span>
Updater.<span class="reserved">prototype</span>.update = <span class="reserved">function</span>()
{
	var getStatus = <span class="reserved">function</span>(anAction)
	{
		var result = true;
		<span class="reserved">if</span> ( COMMONS.isFunction(anAction.checker) )
		{
			result = false;
			try
			{
				result = anAction.checker.call(<span class="reserved">this</span>);
			}
			catch(ex)
			{
				<span class="reserved">this</span>.fLogger.warning(<span class="literal">"update, call of action check method an error caused"</span>, ex);
			}
		}
		<span class="reserved">return</span> result;
	};

	<span class="reserved">if</span> ( !<span class="reserved">this</span>.fLock )
	{
		var action;
		var element;
		var processor;
		<span class="reserved">for</span> (var i = 0; i &lt; <span class="reserved">this</span>.fActions.length; i++)
		{
			action = <span class="reserved">this</span>.fActions[i];
			<span class="reserved">if</span> ( action.on )
			{
				action.status = getStatus.call(<span class="reserved">this</span>, action);
				<span class="reserved">if</span> ( COMMONS.isArray(action.elements) )
				{
					<span class="reserved">for</span>(var j = 0; j &lt; action.elements.length; j++)
					{
						element = UpdaterDOMUtils.getElement(action.elements[j]);
						processor = <span class="reserved">this</span>.getUIProcessor(element, action.status);
						<span class="reserved">if</span> ( COMMONS.isFunction(processor) )
						{
							processor.call(<span class="reserved">this</span>, element, action.status);
						}
					}
				}
			}
		}
	}
};

<span class="comment">/**
 * Indicates that the HTML node UI should be updated.
 *
 * <span class="attrib">@param</span> {Node} The DOM node.
 * <span class="attrib">@param</span> The action status.
 * <span class="attrib">@return</span> {Boolean} If so it returns true, otherwise it returns false.
 */</span>
Updater.<span class="reserved">prototype</span>.acceptUpdateUI = <span class="reserved">function</span>(aNode, aStatus)
{
	<span class="reserved">return</span> aNode.status !== aStatus;
};

<span class="comment">/**
 * DOM node UI processor by defaults.
 * Note: The method can be overrided by custom particular logic.
 *
 * In case of disabled node class name ends with "Off" and
 * enabled node class name ends with "On",  class name will be changed
 * according to the action status.
 * For example:
 * &lt;ul&gt;
 *  &lt;li&gt; Status is true - the class name is "blockOn".
 *  &lt;li&gt; Status is false - the class name is "blockOff".
 * &lt;/ul&gt;
 *
 * <span class="attrib">@param</span> {Node} The DOM node.
 * <span class="attrib">@param</span> {Boolean} The action status.
 * <span class="attrib">@param</span> {Boolean} Returns true if node class name is changed successfully,
 * otherwise - false.
 */</span>
Updater.<span class="reserved">prototype</span>.updateClassName = <span class="reserved">function</span>(aNode, aStatus)
{
	var result = false;
	var className = aNode.className;
	<span class="reserved">if</span> (COMMONS.isString(className) &amp;&amp; /Off\b|On\b/.test(className))
	{
		var newValue = (aStatus) ? className.replace(/Off\b/, <span class="literal">"On"</span>) : className.replace(/On\b/, <span class="literal">"Off"</span>);
		<span class="reserved">if</span> (className !== newValue)
		{
			aNode.className = newValue;
			result = true;
		}
	}
	<span class="reserved">return</span> result;
};

<span class="comment">/**
 * Updates image UI to be according to the action status:
 * &lt;ul&gt;
 *  &lt;li&gt; In case of the image class name conformed by predefined rules image
 *  class will be changed.
 *  For example:
 *  &lt;ul&gt;
 *   &lt;li&gt; Status is true - the class name is "imageOn".
 *   &lt;li&gt; Status is false - the class name is "imageOff".
 *  &lt;/ul&gt;
 *  &lt;li&gt; Otherwise, if the disabled image src ends with "Off" and
 *  enabled image src ends with  "On" image src will be changed
 *  according to the action status.
 *  For example:
 *   &lt;ul&gt;
 *    &lt;li&gt; Status is true - the image src is "imgOn.gif".
 *    &lt;li&gt; Status is false - the image src is "imgOff.gif".
 *  &lt; /ul&gt;
 * &lt;/ul&gt;
 *
 * <span class="attrib">@param</span> {Node} The IMG node.
 * <span class="attrib">@param</span> {Boolean} The action status.
 *
 * <span class="attrib">@see</span> #updateClassName
 */</span>
Updater.<span class="reserved">prototype</span>.updateImageUI = <span class="reserved">function</span>(anImage, aStatus)
{
	<span class="reserved">if</span> ( <span class="reserved">this</span>.acceptUpdateUI(anImage, aStatus) )
	{
		<span class="reserved">if</span> ( !<span class="reserved">this</span>.updateClassName(anImage, aStatus) )
		{
			var src = anImage.src;
			<span class="reserved">if</span> (COMMONS.isString(src) &amp;&amp; /Off\b|On\b/.test(src) )
			{
				var newValue = (aStatus) ? src.replace(/Off\b/, <span class="literal">"On"</span>) : src.replace(/On\b/, <span class="literal">"Off"</span>);
				<span class="reserved">if</span> ( src !== newValue )
				{
					anImage.src = newValue;
				}
			}
		}
		anImage.status = aStatus;
	}
};

<span class="comment">/**
 * Updates form control UI corresponding with the action status:
 * &lt;ul&gt;
 *  &lt;li&gt; In case of the control class name conformed by the
 *  predefined rules control class will be changed.
 *  For example:
 *  &lt;ul&gt;
 *   &lt;li&gt; Status is true - the class name is "inputOn".
 *   &lt;li&gt; Status is false - the class name is "inputOff".
 *  &lt;/ul&gt;
 *  &lt;li&gt; Otherwise, the control will be disabled or enabled
 *  according to the action status.
 * &lt;/ul&gt;
 *
 * <span class="attrib">@param</span> {Node} The form control node.
 * <span class="attrib">@param</span> {Boolean} The action status.
 * <span class="attrib">@see</span> #updateClassName
 */</span>
Updater.<span class="reserved">prototype</span>.updateControlUI = <span class="reserved">function</span>(aControl, aStatus)
{
	<span class="reserved">if</span> ( <span class="reserved">this</span>.acceptUpdateUI(aControl, aStatus) )
	{
		<span class="reserved">if</span> ( !<span class="reserved">this</span>.updateClassName(aControl, aStatus) )
		{
			<span class="reserved">if</span> ( aStatus )
			{
				aControl.disabled = undefined;
				aControl.removeAttribute(<span class="literal">"disabled"</span>);
			}
			<span class="reserved">else</span>
			{
				aControl.disabled = true;
			}
    }
		aControl.status = aStatus;
	}
};

<span class="comment">/**
 * Updates block control UI and all block children
 * according to the action status:
 *
 * &lt;ul&gt;
 *  &lt;li&gt; In case of the block class name is conformed by the
 *  predefined rules block class will be changed.
 *  For example:
 *  &lt;ul&gt;
 *   &lt;li&gt; Status is true - the class name is "divOn".
 *   &lt;li&gt; Status is false - the class name is "divOff".
 *  &lt;/ul&gt;
 *  &lt;li&gt; In case of the block background image is defined
 *  and clip attribute is defined, block backgound clipping will be changed.
 * &lt;/ul&gt;
 *
 * <span class="attrib">@param</span> {Node} The block node.
 * <span class="attrib">@param</span> {Boolean} The action status.
 * <span class="attrib">@see</span> #updateClassName
 */</span>
Updater.<span class="reserved">prototype</span>.updateBlockUI = <span class="reserved">function</span>(aBlock, aStatus)
{
	<span class="reserved">if</span> ( <span class="reserved">this</span>.acceptUpdateUI(aBlock, aStatus) )
	{
		<span class="reserved">if</span> ( !<span class="reserved">this</span>.updateClassName(aBlock, aStatus) )
		{
			var clip = aBlock.clip;
			<span class="reserved">if</span> ( COMMONS.isDefined(clip) )
			{
				clip = COMMONS.toInteger(clip) * 2;
				aBlock.style.backgroundPosition = aStatus ? (<span class="literal">"-"</span> + clip + <span class="literal">"px 0"</span>) : (<span class="literal">"0 0"</span>);
			}
		}
		aBlock.status = aStatus;

    var processor;
		var children = aBlock.childNodes;
		<span class="reserved">for</span>( var i = 0; i &lt; aBlock.childNodes.length; i++ )
		{
			processor = <span class="reserved">this</span>.getUIProcessor( children[i], aStatus);
			<span class="reserved">if</span> ( COMMONS.isFunction(processor) )
			{
				processor.call(<span class="reserved">this</span>, children[i], aStatus);
			}
		}
  }
};

<span class="comment">/**
 * Updatable action manager mouse up listener.
 * If autorepeat functionality on long mouse click is active
 * stops window process.
 *
 * <span class="attrib">@param</span> {Event} The mouse up event.
 */</span>
Updater.<span class="reserved">prototype</span>.mouseUp = <span class="reserved">function</span>(event)
{
	<span class="reserved">if</span> (<span class="reserved">this</span>.fAutoRepeatTaskID !== null)
	{
    window.clearTimeout(<span class="reserved">this</span>.fAutoRepeatTaskID);
    <span class="reserved">this</span>.fAutoRepeatTaskID = null;
  }
};

<span class="comment">/**
 * Forces to call action by action ID.
 *
 * Uses mousedown event listener to autorepeat functionality activation.
 * Note: action autorepeat timeout should be greater than one.
 * 
 * Example of definition:
 * &lt;div onmousedown="manager.call('id')"&gt;&lt;/div&gt;
 */</span>
Updater.<span class="reserved">prototype</span>.call = <span class="reserved">function</span>(aID)
{
	var doInvoke = <span class="reserved">function</span>(anAction)
	{
		var updater = <span class="reserved">this</span>;
		<span class="reserved">if</span> (<span class="reserved">this</span>.fAutoRepeatTaskID !== null)
		{
			window.clearTimeout(<span class="reserved">this</span>.fAutoRepeatTaskID);
			<span class="reserved">this</span>.fAutoRepeatTaskID = null;
		}

		<span class="reserved">if</span> ( <span class="reserved">this</span>.fLock  )
		{
			<span class="reserved">this</span>.fAutoRepeatTaskID = window.setTimeout(<span class="reserved">function</span>()
			{
				doInvoke.call(updater, anAction);
			}, anAction.autoTimeout);
		}
		<span class="reserved">else</span>
		<span class="reserved">if</span> ( <span class="reserved">this</span>.acceptAction(anAction) )
		{
			<span class="reserved">this</span>.fLock = true;
			try
			{
				anAction.call(<span class="reserved">this</span>);
				<span class="reserved">if</span> ( <span class="reserved">this</span>.acceptAction(anAction) )
				{
					<span class="reserved">this</span>.fAutoRepeatTaskID = window.setTimeout(<span class="reserved">function</span>()
					{
						doInvoke.call(updater, anAction);
					}, anAction.autoTimeout);
				}
			}
			catch(ex)
			{
				<span class="reserved">this</span>.fLogger.error(<span class="literal">"doInvoke, action "</span> + <span class="reserved">this</span>.fAction.id + <span class="literal">" invocation error caused"</span>, ex);
			}
			<span class="reserved">this</span>.fLock = false;
		}
	};

	<span class="reserved">if</span> (<span class="reserved">this</span>.fAutoRepeatTaskID !== null)
	{
		window.clearTimeout(<span class="reserved">this</span>.fAutoRepeatTaskID);
		<span class="reserved">this</span>.fAutoRepeatTaskID = null;
	}

	<span class="reserved">if</span> ( !<span class="reserved">this</span>.fLock )
	{
		var action = <span class="reserved">this</span>.getAction(aID);
		<span class="reserved">if</span> (  <span class="reserved">this</span>.acceptAction(action) )
		{
			<span class="reserved">this</span>.fLock = true;
			var updater = <span class="reserved">this</span>;

			try
			{
				action.action.call(<span class="reserved">this</span>);
				<span class="reserved">if</span> ( action.autoTimeout &gt; 1 &amp;&amp; <span class="reserved">this</span>.acceptAction(action) )
				{
					<span class="reserved">this</span>.fAutoRepeatTaskID = window.setTimeout(<span class="reserved">function</span>()
					{
						doInvoke.call(updater, action);
					}, action.autoTimeout);
				}
			}
			catch(ex)
			{
				<span class="reserved">this</span>.fLogger.error(<span class="literal">"invoke, action "</span> + action.id +  <span class="literal">"invocation error caused"</span>, ex);
			}
			<span class="reserved">this</span>.fLock = false;
		}
	}
};</pre>
	<hr>



<!-- ========== START OF NAVBAR ========== -->
<a name="navbar_top"><!-- --></a>
<table border="0" width="100%" cellpadding="1" cellspacing="0">
<tr>
<td colspan=2 bgcolor="#EEEEFF" class="NavBarCell1">
<a name="navbar_top_firstrow"><!-- --></a>
<table border="0" cellpadding="0" cellspacing="3">
  <tr align="center" valign="top">
  
  
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="overview-summary.html"><font class="NavBarFont1"><b>Overview</b></font></a>&nbsp;</td>
  <td bgcolor="#FFFFFF" class="NavBarCell1Rev">	&nbsp;<font class="NavBarFont1Rev"><b>File</b></font>&nbsp;</td>
  

  <td bgcolor="#FFFFFF" class="NavBarCell1"> <font class="NavBarFont1">Class</font>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="overview-tree.html"><font class="NavBarFont1"><b>Tree</b></font></a>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="index-all.html"--><font class="NavBarFont1"><b>Index</b></font></a>&nbsp;</td>
  <td bgcolor="#EEEEFF" class="NavBarCell1">    <a href="help-doc.html"><font class="NavBarFont1"><b>Help</b></font></a>&nbsp;</td>
  </tr>
</table>
</td>
<td bgcolor="#EEEEFF" align="right" valign="top"><em>
<b></b></em>
</td>
</tr>

<tr>
<td bgcolor="white" class="NavBarCell2"><font size="-2">
&nbsp;PREV&nbsp;
&nbsp;NEXT</font></td>
<td bgcolor="white" class="NavBarCell2"><font size="-2">
  <a href="index.html" target="_top"><b>FRAMES</b></a>  &nbsp;
&nbsp;<a href="overview-summary.html" target="_top"><b>NO FRAMES</b></a>
&nbsp;&nbsp;
<script>
  <!--
  if(window==top) {
    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
  }
  //-->
</script>
<noscript>
<a href="allclasses-noframe.html" target=""><b>All Classes</b></a>
</noscript>
</font></td>
</tr>
</table>
<!-- =========== END OF NAVBAR =========== -->

<hr>
<font size="-1">
<p class='footer'>Copyright (c) 2007, <a href='http://soft-amis.com'>SoftAMIS<a></p>
</font>
<div class="jsdoc_ctime">Documentation generated by <a href="http://jsdoc.sourceforge.net/" target="_parent">JSDoc</a> on Tue Jun  5 15:32:30 2007</div>
</body>
</html>
